// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 * Author: Huawei OS Kernel Lab
 * Create: Thu Aug 15 16:14:23 2023
 */

#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/export.h>
#include <liblinux/sched.h>

void
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
{
	liblinux_pal_mutex_init(&lock->pal_mutex);
}
EXPORT_SYMBOL(__mutex_init);

void __sched mutex_lock(struct mutex *lock)
{
	__set_current_state(TASK_UNINTERRUPTIBLE);
	sched_submit_work(current);
	liblinux_pal_mutex_lock(&lock->pal_mutex);
	sched_update_worker(current);
	__set_current_state(TASK_RUNNING);
}
EXPORT_SYMBOL(mutex_lock);

void __sched mutex_unlock(struct mutex *lock)
{
	liblinux_pal_mutex_unlock(&lock->pal_mutex);
}
EXPORT_SYMBOL(mutex_unlock);

int __sched mutex_trylock(struct mutex *lock)
{
	int ret;

	__set_current_state(TASK_UNINTERRUPTIBLE);
	sched_submit_work(current);
	ret = !liblinux_pal_mutex_trylock(&lock->pal_mutex);
	sched_update_worker(current);
	__set_current_state(TASK_RUNNING);
	return ret;
}
EXPORT_SYMBOL(mutex_trylock);

int __sched mutex_lock_interruptible(struct mutex *lock)
{
	__set_current_state(TASK_UNINTERRUPTIBLE);
	sched_submit_work(current);
	liblinux_pal_mutex_lock(&lock->pal_mutex);
	sched_update_worker(current);
	__set_current_state(TASK_RUNNING);
	return 0;
}
EXPORT_SYMBOL(mutex_lock_interruptible);

int __sched mutex_lock_killable(struct mutex *lock)
{
	__set_current_state(TASK_KILLABLE);
	sched_submit_work(current);
	liblinux_pal_mutex_lock(&lock->pal_mutex);
	sched_update_worker(current);
	__set_current_state(TASK_RUNNING);
	return 0;
}
EXPORT_SYMBOL(mutex_lock_killable);

bool mutex_is_locked(struct mutex *lock)
{
	if (liblinux_pal_mutex_is_locked(&lock->pal_mutex))
		return true;
	return false;
}
EXPORT_SYMBOL(mutex_is_locked);

void __sched mutex_lock_io(struct mutex *lock)
{
	__set_current_state(TASK_UNINTERRUPTIBLE);
	sched_submit_work(current);
	liblinux_pal_mutex_lock(&lock->pal_mutex);
	sched_update_worker(current);
	__set_current_state(TASK_RUNNING);
}
EXPORT_SYMBOL(mutex_lock_io);
